<?php
class User {
	private $ip;
	private $data = array();

	public function __construct () {
		$this->ip = $_SERVER['REMOTE_ADDR'];

		# Set initial cookie
		if (!isset($_COOKIE[USER_SESSION])) {
			Logger::log('First visit, setting user cookie.', __METHOD__);

			$this->setData(array('auth_level' => AUTH_LEVEL_GUEST));
		}

		# Update data from cookie
		if (isset($_COOKIE[USER_SESSION])) {
			$this->setData(json_decode($_COOKIE[USER_SESSION]));
		}

		# Store new data from forms
		if (isset($_POST['user_update'])) {
			Logger::log('Updating user data from $_POST.', __METHOD__);

			$this->setData($_POST);
		}

		# If user is logged in/has auth cookie - make sure data validates and update data from DB
		if (isset($_SESSION[USER_SESSION . '_auth']) and isset($_COOKIE[USER_SESSION . '_auth'])) {
			Logger::log('User is signed in, verifying.', __METHOD__);

			$id		= explode('|', $_SESSION[USER_SESSION . '_auth']);
			$id		= $id[0];
			$user	= UsersModel::getByID($id);

			if (
				$user and 
				(
					$_SESSION[USER_SESSION . '_auth'] == 
					$_COOKIE[USER_SESSION . '_auth'] and 
					$_SESSION[USER_SESSION . '_auth'] == 
					"$id|" . md5(conf('general.salt') . $this->ip . $user->getPassword())
				)
			) {
				Logger::log('Users cookie is valid.', __METHOD__);

				$this->setData($user->asArray());
			}
			else {
				Logger::log('Users cookie is not valid.', __METHOD__);

				$this->logout();
			}
		}
		else {
			$this->logout();
		}
	}

	public function login ($email, $password, $remember = false) {
		if ($user = UsersModel::getByEmailPassword($email, $password)) {
			if ($user->getState() < 1) {
				$user->setState(1);
				$user->save();
			}

			$this->setData($user->asArray());

			setcookie(USER_SESSION . '_auth', $user->getUsersId() . '|' . md5(conf('general.salt') . $this->ip . $user->getPassword()), time() + 60 * 60 * 24 * 365, WEBROOT);
			$_SESSION[USER_SESSION . '_auth'] = $user->getUsersId() . '|' . md5(conf('general.salt') . $this->ip . $user->getPassword());

			return true;
		}

		return false;
	}

	public function logout () {
		$this->setData(array('auth_level' => AUTH_LEVEL_GUEST));

		unset($_SESSION[USER_SESSION . '_auth']);
		setcookie(USER_SESSION . '_auth', false, 0, WEBROOT);
	}

	public function __call ($method, $args) {
		$type	= substr($method, 0, 3);
		$k		= strtolower(ccFix(substr($method, 3), '_'));

		if ($type == 'get') {
			if (isset($this->data[$k])) {
				return $this->data[$k];
			}

			return null;
		}
		elseif ($type == 'set') {
			$this->data[$k] = $args[0];

			return $args[0];
		}

		throw new Exception();
	}

	public function asArray () {
		return $this->data;
	}

	public function getData ($k = false) {
		return $k === false ? $this->data : (isset($this->data[$k]) ? $this->data[$k] : null);
	}

	public function setData ($data) {
		foreach ($data as $k => $v) {
			$this->data[$k] = $v;
		}

		setcookie(USER_SESSION, json_encode($this->data), time() + 60 * 60 * 24 * 365, WEBROOT);
	}

	public function authLevel () {
		return $this->getData('auth_level');
	}
}
